package jp.co.dailyReport.dailyReport;

import java.util.Calendar;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import jp.co.dailyReport.ExecuterManager;
import jp.co.dailyReport.ConnectionFactory;
import jp.co.dailyReport.DataUnavailableException;
import jp.co.dailyReport.dailyReport.sql.DailyReportDeleteExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportInsertExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportLoadExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportLoadMaxIDExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportsLoadExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportUpdateExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportLoadForEditExecuter;
import jp.co.dailyReport.dailyReport.sql.DailyReportLoadMaxIdOfStaffIdExecuter;
import jp.co.dailyReport.staff.Staff;
import jp.co.dailyReport.PermissionException;
import jp.co.dailyReport.PermissionManager;
import java.util.ArrayList;

/**
 * 日報情報管理クラス
 */
public class DailyReportManager {

	private static Logger log = Logger.getLogger(DailyReportManager.class);

	/**
	 * 日報情報を取得します。
	 * 
	 * @return 日報オブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static DailyReport[] load() throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportsLoadExecuter dailyReportsLoadExecuter = new DailyReportsLoadExecuter();
		Object objs[] = (Object[]) null;
		try {
			objs =
				ExecuterManager.execute(
					connectionFactory,
					dailyReportsLoadExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if (objs == null || objs.length == 0) {
			return new DailyReport[0];
		} else {
			return (DailyReport[]) objs;
		}
	}

	/**
	 * 社員が指定操作可能な日報情報を取得します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param methodId 操作方法ID(PermissionManagerで定義)
	 * @return 日報オブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static DailyReport[] load(Staff staff,int methodId)
		 throws DataUnavailableException {

		DailyReport[] dailyReports = load();
		ArrayList answer = new ArrayList();
		for(int i =0; i < dailyReports.length;i++){
			if(PermissionManager.hasPermission(staff,dailyReports[i],methodId)){
				answer.add(dailyReports[i]);
			}
		}
		return (DailyReport[])answer.toArray(new DailyReport[0]);
	}

	/**
	 * 日報情報を取得します。
	 * 
	 * @param staff 社員オブジェクト
	 * @return 日報オブジェクトの配列
	 * @throws DataUnavailableException
	 */
	public static DailyReport[] load(Staff staff)
		 throws DataUnavailableException {
		return load(staff,PermissionManager.METHOD_READ);
	}

	/**
	 * 日報情報を取得します。
	 * 
	 * @param dailyReportId 日報ID
	 * @return 日報オブジェクト
	 * @throws DataUnavailableException
	 */
	public static DailyReport load(int dailyReportId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportLoadExecuter dailyReportLoadExecuter = new DailyReportLoadExecuter(dailyReportId);
		Object objs[] = null;

		try {
			objs = ExecuterManager.execute(connectionFactory, dailyReportLoadExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if (objs == null || objs.length == 0) {

			return new DailyReport();
		} else {
			return (DailyReport) objs[0];
		}
	}

	/**
	 * 日報情報を取得します。
	 * 
	 * @param workDate 作業日
	 * @param staffId 社員ID
	 * @return 日報オブジェクト
	 * @throws DataUnavailableException
	 */
	public static DailyReport load(Calendar workDate,int staffId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportLoadForEditExecuter dailyReportLoadForEditExecuter = new DailyReportLoadForEditExecuter(workDate,staffId);
		Object objs[] = null;

		try {
			objs = ExecuterManager.execute(connectionFactory, dailyReportLoadForEditExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if (objs == null || objs.length == 0) {
			return new DailyReport();
		} else {
			return (DailyReport) objs[0];
		}
	}

	/**
	 * 日報IDの最大値を取得します。
	 * 
	 * @return 日報IDの最大値
	 * @throws DataUnavailableException
	 */
	public static int loadMaxId() throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportLoadMaxIDExecuter dailyReportLoadMaxIDExecuter = new DailyReportLoadMaxIDExecuter();
		Object objs[] = (Object[]) null;

		try {
			objs = ExecuterManager.execute(connectionFactory, dailyReportLoadMaxIDExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if (objs == null || objs.length == 0) {
			return 0;
		} else {
			return Integer.parseInt((String) objs[0]);
		}
	}

	/**
	 * 日報IDの最大値を取得します。
	 * 
	 * @param staffId 社員ID
	 * @return 日報IDの最大値
	 * @throws DataUnavailableException
	 */
	public static int loadMaxId(int staffId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportLoadMaxIdOfStaffIdExecuter dailyReportLoadMaxIdOfStaffIdExecuter = new DailyReportLoadMaxIdOfStaffIdExecuter(staffId);
		Object objs[] = (Object[]) null;

		try {
			objs = ExecuterManager.execute(connectionFactory, dailyReportLoadMaxIdOfStaffIdExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		if (objs == null || objs.length == 0) {
			return 0;
		} else {
			return Integer.parseInt((String) objs[0]);
		}
	}

	/**
	 * 社員の権限で日報情報を更新します。<BR>
	 * 更新した日報情報の日報IDから日報作業項目情報を削除します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param dailyReport 日報オブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void update(Staff staff ,DailyReport dailyReport)
		 throws DataUnavailableException ,PermissionException{

		if(PermissionManager.hasPermission(staff,dailyReport,PermissionManager.METHOD_WRITE)){
			ConnectionFactory connectionFactory = new ConnectionFactory();
			DailyReportUpdateExecuter dailyReportUpdateExecuter = new DailyReportUpdateExecuter(dailyReport);
			try {
				ExecuterManager.execute(connectionFactory, dailyReportUpdateExecuter);
				DailyReportWorkItemManager.delete(dailyReport.getDailyReportId());
			} catch (SQLException sqle) {
				log.error(sqle.toString(), sqle);
				throw new DataUnavailableException(sqle.toString());
			}
		}else{
			throw new PermissionException(" Permission denied to update dailyReport");
		}
	}

	/**
	 * 日報情報を登録します。
	 * 
	 * @param dailyReport 日報オブジェクト
	 * @throws DataUnavailableException
	 */
	public static void insert(DailyReport dailyReport) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportInsertExecuter dailyReportInsertExecuter = new DailyReportInsertExecuter(dailyReport);
		try {
			ExecuterManager.execute(connectionFactory, dailyReportInsertExecuter);
		} catch (SQLException sqle) {
			log.error(sqle.toString(), sqle);
			throw new DataUnavailableException(sqle.toString());
		}
	}

	/**
	 * 社員の権限で日報情報を登録します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param dailyReport 日報オブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void insert(Staff staff ,DailyReport dailyReport)
		 throws DataUnavailableException ,PermissionException{

		if(PermissionManager.hasPermission(staff,dailyReport,PermissionManager.METHOD_WRITE)){
			insert(dailyReport);
		}else{
			throw new PermissionException(" Permission denied to insert dailyReport");
		}
	}

	/**
	 * 社員の権限で日報情報を削除します。
	 * 
	 * @param staff 社員オブジェクト
	 * @param dailyReport 日報オブジェクト
	 * @throws DataUnavailableException、PermissionException 権限が無いときに発生します。
	 */
	public static void delete(Staff staff ,DailyReport dailyReport)
		 throws DataUnavailableException ,PermissionException{

		if(PermissionManager.hasPermission(staff,dailyReport,PermissionManager.METHOD_WRITE)){
			ConnectionFactory connectionFactory = new ConnectionFactory();
			DailyReportDeleteExecuter dailyReportDeleteExecuter = new DailyReportDeleteExecuter(dailyReport.getDailyReportId());
			try {
				ExecuterManager.execute(connectionFactory, dailyReportDeleteExecuter);
				DailyReportWorkItemManager.delete(dailyReport.getDailyReportId());
			} catch (SQLException sqle) {
				log.error(sqle.toString(), sqle);
				throw new DataUnavailableException(sqle.toString());
			}
		}else{
			throw new PermissionException(" Permission denied to delete dailyReport");
		}
	}

	/**
	 * 日報情報の存在チェックを行います。
	 * 
	 * @param dailyReportId 日報ID
	 * @return true→存在する、false→存在しない
	 * @throws DataUnavailableException
	 */
	public static boolean isExist(int dailyReportId) throws DataUnavailableException {

		ConnectionFactory connectionFactory = new ConnectionFactory();
		DailyReportLoadExecuter dailyReportLoadExecuter = new DailyReportLoadExecuter(dailyReportId);
		Object objs[] = null;
		try {
			objs = ExecuterManager.execute(connectionFactory, dailyReportLoadExecuter);
		} catch (SQLException sqle) {
			throw new DataUnavailableException(sqle.toString());
		}
		return objs != null && objs.length != 0;
	}
}